<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>    
    <div id="app">      
        <!--  1、监听一个ref。 -->
        <p>age:{{age}}</p>
        <p>wifeAge:{{wifeAge}}</p>
        <input type="button" value="修改age" @click="changeAge" >
        <hr/>

        <!--  2、监听一个响应式对象 -->

        <p>person.name:{{person.name}}</p>
        <p>person.wife.name:{{person.wife.name}}</p>
        <input type="button" value="修改wife的name" @click="changeWifeName" >
        <hr/>  

        <!--  3、监听一个回调函数 -->       
        
        <p>count:{{count}}</p>         
        <input type="button" value="修改count" @click="changeCount" />

        <p>inc:{{inc}}</p> 
        <input type="button" value="修改inc" @click="changeInc" />
        <hr/>

        <!-- 4、体现deep （当返回值是一个对象时，需要使用deep:true -->
        <p>a:{{objReactive.a}}</p>
        <p>b.b1:{{objReactive.b.b1}}</p>
        <input type="button" value="修改deep" @click="changeDeep">
    </div>
</body>
</html>

<script src="./js/vue.global.js"></script>
<script>    

     const {createApp,ref,reactive,watch} = Vue;

    let app = createApp({
        setup(){

            // 1、监听一个ref。

            let age = ref(18);

            let wifeAge = ref(0);

            watch(age,function(newVal,oldVal){
                console.log("watch",newVal,oldVal);
                wifeAge.value = newVal + 3;
            },{
                immediate:true
            })

            function changeAge(){
                age.value--;
            }

            // 2、监听一个响应式对象

            let person = reactive({
                name:"王义鑫",
                age:12,
                wife:{
                    name:"范冰冰"                    
                }
            })
            
            watch(person,function(){
                console.log("watch person");
            })

            function changeWifeName(){                
                console.log("changeWifeName");
                
                // person = {};//这样修改，不会监听到，因为，你已经让person变成了普通对象，而不是proxy对象

                // person.wife = {};//可以
                // person.wife.name="李冰冰";//可以
            }

            // 3、监听一个回调函数
            let count = ref(12);
            let inc = ref(2);

            // 因为回调函数里使用了count和inc，所以，相当于监听了 count和inc的变化
            watch(()=>count.value+inc.value,function(newVal){
          // watch([count,inc],function(newVal){
                console.log("watch监听回调函数newVal",newVal);
            },{
                immediate:true
            });
                
            function changeCount(){
                count.value ++;
            }

            function changeInc(){
                inc.value ++;
            }

            // 4、体现deep

            let objReactive = reactive(
                {
                    a:1,
                    b:{
                        b1:2,
                        b2:3
                    }
                }
            )

            // 当监听的源是回调函数时，只有在 回调函数的返回值发生变化时，才触发watch。
            // 那么，如果：返回值是引用类型，那么地址不变，返回值就不会变。所以说,改变对象的属性时,并不会引起watch。
            // 所以说:  当回调函数（侦听源）的返回值是(响应式)对象时。需要使用deep。
            watch(()=>objReactive,function(){
                console.log("watch,deep");
            },{
                deep:true
            })

            function changeDeep(){
                console.log("changeDeep");
                // objReactive.a ++;//并没有改变 objReactive对象，只是改变了对象的属性。
                objReactive.b.b1 ++;
            }
            
            
            return {
              age,wifeAge,changeAge,
              person,changeWifeName,
              count,inc,changeCount,changeInc,
              objReactive,changeDeep
            }
        }
    })

    app.mount("#app");

</script>